
#include <Digraph.h>

Digraph::Digraph() : num(0), added(0)
{
}

Digraph::Digraph(int numElements) : num(numElements), added(0)
{
	main = new MainNode[num];
}

void Digraph::create(int numElements)
{
	num = numElements;
	added = 0;
	main = new MainNode[num];
}

Link* Digraph::allocLink(Element symbol, Element link)
{
	Link* temp;
	temp = new Link;
	temp->symbol = symbol;
	temp->link = link;
	temp->next = 0;
	return temp;
}

void Digraph::add(Element elem)
{
	if ( !ifExists(elem) ) {
		main[added].element = elem;
		added++;
	}
}

void Digraph::add(Element elem, Element symbol, Element link)
{
	Link* tempLink;
	if ( !ifExists(elem) ) {
		main[added].element = elem;
		main[added].links = allocLink(symbol, link);
		added++;
	} else {
		Link *tempLink, *temp2;
		Element temp(elem);
		for ( int i = 0; i < num; i++ )
			if ( main[i].element == temp ) {
				tempLink = main[i].links;
				while ( tempLink->next )
					tempLink = tempLink->next;
				temp2 = allocLink(symbol, link);
				tempLink->next = temp2;
				main[i].numLinks++;
				return;
			}
	}
}

int Digraph::ifExists(Element elem)
{
	for ( int i = 0; i < num; i++ )
		if ( main[i].element.length() )
			if ( main[i].element == elem )
				return 1;
	return 0;
}

int Digraph::ifExists(Element elem, Element symbol)
{
	Link* tempLink;
	for ( int i = 0; i < num; i++ )
		if ( main[i].element.length() ) {
			if ( main[i].element == elem ) {
				tempLink = main[i].links;
				while ( tempLink ) {
					if ( tempLink->symbol == symbol )
						return 1;
					tempLink = tempLink->next;
				}
				return 1;
			}
		}
	return 0;
}

Element* Digraph::getSymbols(Element elem, int& numSym)
{
	Link* trav;
	Element* elements;
	int j;

	for ( int i = 0; i < num; i++ )
		if ( main[i].element == elem ) {
			elements = new Element[main[i].numLinks];
			trav = main[i].links;
			j = 0;
			while ( trav ) {
				elements[j] = trav->symbol;
				j++;
				trav = trav->next;
			}
			numSym = j;
			return elements;
		}
	numSym = 0;
	return 0;
}

Element Digraph::getLink(Element elem, Element symbol)
{
	Link* trav;
	Element link;

	for ( int i = 0; i < num; i++ )
		if ( main[i].element == elem ) {
			trav = main[i].links;
			while ( trav ) {
				if ( trav->symbol == symbol ) {
					link = trav->link;
					return link;
				}
				trav = trav->next;
			}
		}
	return elem;
}

Digraph::~Digraph()
{
	Link* trav;
	for ( int i = 0; i < num; i++ ) {
		for ( trav = main[i].links; trav; trav = main[i].links ) {
			main[i].links = trav->next;
			delete trav;
		}
	}
	delete[] main;
}

ostream& operator<<(ostream& os, const Digraph& dg)
{
	Link* trav;
	for ( int i = 0; i < dg.num; i++ ) {
		os << dg.main[i].element << " : ";
		trav = dg.main[i].links;
		while ( trav ) {
			os << "(" << trav->symbol
				<< "," << trav->link << ") ";
			trav = trav->next;
		}
		os << endl;
	}
	return os;
}

